package com.obaamilos.accesscontrol;

import jade.core.AID;
import jade.core.Agent;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

public class LoginTestes  extends Agent {
	/**
	 * 
	 */
	private static final long serialVersionUID = 4292598380076856457L;

	// Interface Gr�fica com o Usu�rio
	private LoginTestesGUI meuGui;
	
	private String strResposta;
	
	// Lista de agentes encontrados no ambiente
	private AID[] agentesAC;
	private AID[] agentesQry;
	private AID[] agentesUpd;

	// Inicializa��o
	protected void setup() {
		// Aguarda agentes AccessControl/Query/Update subirem...
		try {
		    Thread.sleep(2000);
		} catch(InterruptedException ex) {
		    Thread.currentThread().interrupt();
		}		

		DFAgentDescription template_qry = new DFAgentDescription();
		ServiceDescription sd_qry = new ServiceDescription();
		sd_qry.setType("AgenteQuery");
		
		template_qry.addServices(sd_qry);
		// Obtem todos os agentes do ambiente que sejam do tipo AgenteQuery
		try {
			DFAgentDescription[] result = DFService.search(this, template_qry); 
			System.out.println("Retorno da busca de agentes query:");
			agentesQry = new AID[result.length];
			for (int i = 0; i < result.length; ++i) {
				agentesQry[i] = result[i].getName();
				System.out.println(agentesQry[i].getName());
			}
		}
		catch (FIPAException fe) {
			fe.printStackTrace();
		}

		DFAgentDescription template_upd = new DFAgentDescription();
		ServiceDescription sd_upd = new ServiceDescription();
		sd_upd.setType("AgenteUpdate");
		template_upd.addServices(sd_upd);
		try {
			DFAgentDescription[] result = DFService.search(this, template_upd); 
			System.out.println("Retorno da busca de agentes update:");
			agentesUpd = new AID[result.length];
			for (int i = 0; i < result.length; ++i) {
				agentesUpd[i] = result[i].getName();
				System.out.println(agentesUpd[i].getName());
			}
		}
		catch (FIPAException fe) {
			fe.printStackTrace();
		}

		DFAgentDescription template_ac = new DFAgentDescription();
		ServiceDescription sd_ac = new ServiceDescription();
		sd_ac.setType("AgenteAccessControl");
		template_ac.addServices(sd_ac);
		try {
			DFAgentDescription[] result = DFService.search(this, template_ac); 
			System.out.println("Retorno da busca de agentes accesscontrol:");
			agentesAC = new AID[result.length];
			for (int i = 0; i < result.length; ++i) {
				agentesAC[i] = result[i].getName();
				System.out.println(agentesAC[i].getName());
			}
		}
		catch (FIPAException fe) {
			fe.printStackTrace();
		}

		// Cria e apresenta a interface 
		meuGui = new LoginTestesGUI(this);

        meuGui.getTxtAgQry().setText(Integer.toString(agentesQry.length));
        meuGui.getTxtAgUpd().setText(Integer.toString(agentesUpd.length));
        meuGui.getTxtAgAC().setText(Integer.toString(agentesAC.length));

		meuGui.showGui();
		
		configuraLocalTDB(meuGui.getTxtLocalTDB().getText());
		
		// Busca resursos...
		atualizaRecursos();
	}
	
	public void configuraLocalTDB(String pLocal) {
		EnviaSolicitacaoAcesso("TDB<aa>"+pLocal+"<aa>");
	}
	
	public String realizaLogin(String pLogin, String pSenha) {
		String mRet;
		mRet = "LOGIN<aa>"+pLogin+"<aa>"+pSenha+"<aa>";
		mRet = EnviaSolicitacaoAcesso(mRet);
		if (mRet.length() > 10) {
			String strAux = EnviaSolicitacaoAcesso("USER<aa>"+mRet+"<aa>");
			System.out.println(strAux);
			String [] strAuxs = strAux.split(System.getProperty("line.separator"));
			if (strAuxs.length > 1) {
				System.out.println(strAuxs[0]);
				String [] strAuxs2 = strAuxs[0].split("nome:");
				meuGui.getTxtID().setText(pLogin);
				meuGui.getTxtToken().setText(mRet);
				meuGui.getTxtNome().setText(strAuxs2[1].replace("]", ""));
				String strPerfis = strAuxs[1].replace("perfil -> ", "");
				for (int j=2; j<strAuxs.length; j++) {
					strPerfis += System.getProperty("line.separator")+strAuxs[j];
				}
				meuGui.getTxtPerfisUsuario().setText(strPerfis);
				meuGui.getTxtLogin().setText("");
				meuGui.getTxtSenha().setText("");
			}
		}
		return(mRet);
	}
	
	public void realizaLogout(String pToken) {
		EnviaSolicitacaoAcesso("LOGOUT<aa>"+pToken+"<aa>");
	}

	public void atualizaRecursos() {
		String m_comando = meuGui.getTxtLocalTDB().getText()+"<separa>"+System.getProperty("line.separator")+
				"PREFIX ca: <http://www.semanticweb.org/controle_acesso#>"+System.getProperty("line.separator")+
				"SELECT ?u"+System.getProperty("line.separator")+
				"WHERE { ?u a ca:Learning_Object }";

		meuGui.getLstRecursosModel().clear();
		meuGui.getLstRecursosModel().addElement("[AnyResource]");

		String mNomeRecurso;
		strResposta = "";
		EnviaQuery(m_comando);
		String [] mLst = strResposta.split(System.getProperty("line.separator"));
		for (int i=1; i < mLst.length; i++) {
			mNomeRecurso = mLst[i].replace("[", "[Learning_Object - ");
			meuGui.getLstRecursosModel().addElement(mNomeRecurso);
		}
		
		m_comando = meuGui.getTxtLocalTDB().getText()+"<separa>"+System.getProperty("line.separator")+
				"PREFIX ca: <http://www.semanticweb.org/controle_acesso#>"+System.getProperty("line.separator")+
				"SELECT ?u"+System.getProperty("line.separator")+
				"WHERE { ?u a ca:Application }";
		strResposta = "";
		EnviaQuery(m_comando);
		String [] mLst2 = strResposta.split(System.getProperty("line.separator"));
		for (int i=1; i < mLst2.length; i++) {
			mNomeRecurso = mLst2[i].replace("[", "[ApplicationAsResource - ");
			meuGui.getLstRecursosModel().addElement(mNomeRecurso);
		}
		meuGui.getLstRecursos().setSelectedIndex(0);
	}
	
	private MessageTemplate mt;   // Template  para receber respostas
	
	public String EnviaSolicitacaoAcesso(String pComando) {
		String strRet = "";
		if (agentesAC.length > 0) {
			// Envia o comando a um dos agentes de controle de acesso
			ACLMessage req = new ACLMessage(ACLMessage.REQUEST);
			req.addReceiver(agentesAC[0]);
			System.out.println("Teste selecionou agente " + agentesAC[0].getName());
			req.setContent(pComando);
			req.setConversationId("testa-accesscontrol");
			req.setReplyWith("req"+System.currentTimeMillis()); // Valor �nico
			send(req);
			System.out.println("Teste enviou requisicao accesscontrol");

			// Prepara "template" para receber respostas
			mt = MessageTemplate.and(MessageTemplate.MatchConversationId("testa-accesscontrol"),
				 MessageTemplate.MatchPerformative(ACLMessage.INFORM));

			ACLMessage resposta = blockingReceive(mt);
			if (resposta != null) {
				// Conjunto local do agentes recebido
				if (resposta.getPerformative() == ACLMessage.INFORM) {
					// Grava o retorno...
					System.out.println("Access Recebeu resposta n�o nula e INFORM");
					strRet = resposta.getContent();
					
					//meuGui.setTxtResposta(strResposta);
				}
				else {
					System.out.println("Resposta inesperada.");
				}
				System.out.println("Query concluido.");
			}
		}
		return(strRet);
	}
	 
	public void EnviaQuery(final String pComando) {
		//System.out.println("Iniciando teste, comando " + pComando);
		// Testa Query
		if (agentesQry.length > 0) {
			// Envia o comando a todos os agentes encontrados
			ACLMessage req = new ACLMessage(ACLMessage.REQUEST);
			for (int i = 0; i < agentesQry.length; ++i) {
				req.addReceiver(agentesQry[i]);
				System.out.println("Teste selecionou agente " + agentesQry[i].getName());
			}
			req.setContent(pComando);
			req.setConversationId("testa-query");
			req.setReplyWith("req"+System.currentTimeMillis()); // Valor �nico
			//myAgent.send(req);
			send(req);
			System.out.println("Teste enviou requisicao query");

			// Prepara "template" para receber respostas
			mt = MessageTemplate.and(MessageTemplate.MatchConversationId("testa-query"),
					MessageTemplate.MatchPerformative(ACLMessage.INFORM));

			ACLMessage resposta = blockingReceive(mt);
			if (resposta != null) {
				// Conjunto local do agentes recebido
				if (resposta.getPerformative() == ACLMessage.INFORM) {
					// Grava o retorno...
					System.out.println("Query Recebeu resposta n�o nula e INFORM");
					strResposta = resposta.getContent();
					
					//meuGui.setTxtResposta(strResposta);
				}
				else {
					System.out.println("Resposta inesperada.");
				}
				System.out.println("Query concluido.");
			}
		}
	}

	// Opera��o de shutDown
	protected void takeDown() {
		// Fecha o GUI
		meuGui.dispose();
	}
}
